Update SAML documentation#1084
Conversation
…the future release. (#1074)
…pgrade guide (#1080) * Add changes from products repository (PR 255 and 256), optimize for readability in docs site * Reorganize IdentityServer upgrade guide overview for improved clarity and consistency * Add IdentityServer4 to Duende IdentityServer v8.0 upgrade guide detailing migration steps, breaking changes, and schema updates.
|
@maartenba the SAML 2.0 Concepts page was meant to be a general overview of SAML (with maybe some light linking into our implementation). Not sure if adding code blocks and implementation details is right for that page. |
…ards-compat language, add mermaid diagrams for SP-initiated SSO and SLO flows, code-block protocol terms in prose, fix ambiguous pronouns
|
Addressed review feedback in 21c08bf:
Not addressed (not a docs change): |
… on RequestedClaimTypes interaction
…ed envs, correct reasons are size limits, client exposure, and auditability
…ceProviderAdmin, ServiceProviderEntityId, encryption), fix NameID formats (email+unspecified only), correct ISamlSigninStateStore (in-memory default, EF for prod), rename ISamlSigninInteractionResponseGenerator, update ISamlInteractionService deprecation, add EF Core store docs
|
Addressed bhazen's review feedback in c9d2d9b: Removed (platform-only / not in v8):
Fixed:
Added:
|
| The Identity Provider signs the assertion with its private key. The Service Provider validates the signature before trusting any claims inside. IdentityServer builds assertions automatically when it processes a SAML sign-in request. You control what attributes appear in assertions via claim mappings — see [`SamlOptions.DefaultClaimMappings` and `SamlServiceProvider.ClaimMappings`](/identityserver/saml/configuration.md#default-claim-mappings). The signing behavior is configured via the [`SamlSigningBehavior` enum](/identityserver/saml/configuration.md#samlsigningbehavior). | ||
| The Identity Provider signs the assertion with its private key. The Service Provider validates the signature before trusting any claims inside. | ||
|
|
||
| In IdentityServer, you control what attributes appear in assertions via [claim mappings](/identityserver/saml/configuration.md#default-claim-mappings) and configure signing via [`SamlSigningBehavior`](/identityserver/saml/configuration.md#samlsigningbehavior). |
There was a problem hiding this comment.
There's a bit more to what controls which attributes appear in the assertions. There's a few relevant settings on the Service Provider:
AllowedScopes- controls which claims can be requested by a service provider by which scopes are allowed here. These should be identity resources which contain the appropriate scopes.RequestedClaimTypes- default claim types to request
If RequestedClaimTypes is not set, all claim types resolved from AllowedScopes will be used. RequestedClaimTypes is a way to set the claims to a default subset of AllowedScopes.
The intent was to set this up such that someday we could support Attribute Consuming Services from Authn requests.
The claim mappings then map any of the claims from the OIDC claim name to whatever is in the mapping.
| Metadata makes federation scalable. Instead of manually exchanging certificates and endpoint URLs out-of-band, parties import each other's metadata and configure trust automatically. Large identity federations — such as InCommon (over 1,000 organizations) — rely on machine-readable metadata to coordinate trust across hundreds or thousands of participants. | ||
| Metadata makes federation scalable. Instead of manually exchanging certificates and endpoint URLs out-of-band, parties import each other's metadata and configure trust automatically. | ||
|
|
||
| IdentityServer publishes its IdP metadata at `/saml/metadata`. Share this URL with each Service Provider during federation setup so they can automatically discover your signing certificates, NameID formats, and endpoint locations. See the [metadata endpoint](/identityserver/saml/endpoints.md#metadata-endpoint) for more details. |
There was a problem hiding this comment.
The SAML metadata is published to the EntityId of IdentityServer when acting as an IdP to be compliant with the SAML metadata spec. By default that's /Saml2. This can be be modified by a couple different properties on SamlOptions:
- Changing the
EntityIdPathsetting which defaults to/Saml2(i.e. changing it tofoowould make the metadata route/foo - Changing the
EntityIdwhich makes the metadata route whatever the path of the value forEntityIdis if it http or https url
|
|
||
| ### Front-Channel Logout | ||
|
|
||
| IdentityServer uses front-channel logout, which means logout notifications travel through the user's browser via redirects. The IdP redirects the browser to each SP's SLO endpoint in sequence, and each SP terminates its local session before the browser is redirected onward. This approach is simpler to implement than back-channel (server-to-server) logout, but it requires the user's browser to remain open and active throughout the logout sequence. Back-channel logout is not supported. |
There was a problem hiding this comment.
This is what the spec describes, but it's not how we implemented it. Rather than the redirect chain, we're using iframes. It is not spec compliant, but it prevents the entire processing from failing if one SP does not respond and ends up being a bit less brittle. So we render all the iframes on the same page as where we do for OIDC and record responses if we receive them to generate a proper final status.
| ### Timeouts and Edge Cases | ||
|
|
||
| For this reason, many deployments supplement SLO — or replace it entirely — with short session lifetimes and per-application logout as a simpler fallback. | ||
| If an SP is unreachable or the user closes the browser mid-flow, the logout sequence may not complete for all SPs. Short session lifetimes and per-application logout are common supplements to SLO in deployments where reliability matters more than protocol completeness. You can tune logout timeout behavior via `SamlOptions` to balance user experience against thoroughness. |
There was a problem hiding this comment.
This option controls the TTL for records in the ISamlLogoutSessionStore, but a bigger factor may be how long the user waits on the page where the iframes are rendered. If the user clicks off of that before all the SPs in the session respond, it will result in a status as if the logout sequence didn't complete. Maybe it's worth including something about that here.
| For this reason, many deployments supplement SLO — or replace it entirely — with short session lifetimes and per-application logout as a simpler fallback. | ||
| If an SP is unreachable or the user closes the browser mid-flow, the logout sequence may not complete for all SPs. Short session lifetimes and per-application logout are common supplements to SLO in deployments where reliability matters more than protocol completeness. You can tune logout timeout behavior via `SamlOptions` to balance user experience against thoroughness. | ||
|
|
||
| In IdentityServer, you configure SLO per SP by setting `SamlServiceProvider.SingleLogoutServiceUrl`. IdentityServer then sends front-channel logout notifications to all SPs with a configured SLO endpoint when a user's session ends. See the [logout endpoint](/identityserver/saml/endpoints.md#logout-endpoint) and [`ISamlLogoutNotificationService`](/identityserver/saml/extensibility.md#isamllogoutnotificationservice) for customization options. |
There was a problem hiding this comment.
Right now we only support the HttpRedirect binding for SLO as that restriction alleviated some potential issues for us. It is probably worth calling that out here.
| ## ISaml2MetadataResponseGenerator | ||
|
|
||
| `ISaml2MetadataResponseGenerator` generates the IdP metadata document served at the | ||
| `/saml/metadata` endpoint. SAML metadata describes the IdP's capabilities, endpoints, and signing |
There was a problem hiding this comment.
| `/saml/metadata` endpoint. SAML metadata describes the IdP's capabilities, endpoints, and signing | |
| `/Saml2` endpoint. SAML metadata describes the IdP's capabilities, endpoints, and signing |
| ### 1. Register SAML Services | ||
|
|
||
| Call `AddSaml()` on the IdentityServer builder: | ||
| Call `AddSaml()` on the IdentityServer builder to enable all SAML endpoints (IdP-initiated SSO requires explicit opt-in): |
There was a problem hiding this comment.
| Call `AddSaml()` on the IdentityServer builder to enable all SAML endpoints (IdP-initiated SSO requires explicit opt-in): | |
| Call `AddSaml()` on the IdentityServer builder to enable all SAML endpoints: |
|
|
||
| ## Protocol Endpoints | ||
|
|
||
| SAML 2.0 endpoints are registered under the `/saml` path prefix: |
There was a problem hiding this comment.
| SAML 2.0 endpoints are registered under the `/Saml2` path prefix: |
| | Endpoint | Path | | ||
| | ----------------- | ----------------------- | | ||
| | Metadata | `/saml/metadata` | | ||
| | Sign-in | `/saml/signin` | | ||
| | Sign-in Callback | `/saml/signin_callback` | | ||
| | IdP-initiated SSO | `/saml/idp-initiated` | | ||
| | Logout | `/saml/logout` | | ||
| | Logout Callback | `/saml/logout_callback` | |
There was a problem hiding this comment.
| | Logout Callback | `/saml/logout_callback` | | |
| | Endpoint | Path | | |
| | ----------------- | ----------------------- | | |
| | Metadata | `/Saml2` | | |
| | Sign-in | `/Saml2/SSO` | | |
| | Sign-in Callback | `/Saml2/SSO/Callback` | | |
| | Logout | `/Saml2/SLO` | | |
| | Logout Callback | `/Saml2/SLO/Callback` | |
| The migration creates five new tables in the configuration database: `SamlServiceProviders`, | ||
| `SamlServiceProviderAssertionConsumerServices`, `SamlServiceProviderSigningCertificates`, | ||
| `SamlServiceProviderEncryptionCertificates`, and `SamlServiceProviderClaimMappings`. | ||
| The migration creates several new tables in the configuration database: `SamlServiceProviders`, |
There was a problem hiding this comment.
There are new tables for operational data for SAML for sign-in and logout too. As of the time of writing this comment, the PR that adds the logout tables is still open.
Additional review findingsCross-referenced the docs against the current source code. These are issues not already covered by existing review comments.
|
May 15, 2026 /
2249a0935853b79a8453f1baab979f21b4b7255e